#include "stdint.h"
#include "stdio.h"
#include "string.h"
#include "microConfig.h"
#include "microTime.h"
#include "microDelay.h"
#include "microMemory.h"
#include "microTask.h"


/* 优先级任务头节点 */
MicroListType g_typeMicroListTaskHead[MICRO_TASK_PRIORITY_MAX_VALUE + 1] = {0};
/* 当前任务头节点指针 */
MicroTaskType *g_ptypeTaskCurrentHandle = NULL;

/* 优先级列表 */
int8_t g_cTaskPriorityValid[MICRO_TASK_PRIORITY_MAX_VALUE + 1] = {0};


void vMicroTaskIdle(void *pvValue)
{

}

void vMicroTaskIdleInit(void)
{
    MicroTaskType *ptypeTaskHandle = NULL;

    ptypeTaskHandle = ptypeMicroTaskGreat("IDLE", MICRO_TASK_PRIORITY_MAX_VALUE, vMicroTaskIdle);
    if(ptypeTaskHandle == NULL)
        return;

    g_ptypeTaskCurrentHandle = ptypeTaskHandle;
}

void vMicroTaskInit(void)
{
    int8_t i = 0;

    /* 初始化全部优化级任务头节点 */
    for(i = 0; i < MICRO_TASK_PRIORITY_MAX_VALUE + 1; ++i)
    {
        cMicroListInit(&g_typeMicroListTaskHead[i], MICRO_TASK_PRIORITY_MAX_VALUE);
    }

    /* 初始化空闲任务 */
    vMicroTaskIdleInit();
}

MicroTaskType *ptypeMicroTaskCurrentGet(void)
{
    return g_ptypeTaskCurrentHandle;
}

int8_t cMicroTaskResume(MicroTaskType *ptypeTaskHandle)
{
    if(ptypeTaskHandle == NULL)
        return 1;

    if(ptypeTaskHandle->priority > MICRO_TASK_PRIORITY_MAX_VALUE)
        return 2;

    /* 插入到当前优先级任务链表的最后 */
    cMicroListInsertEnd(&g_typeMicroListTaskHead[ptypeTaskHandle->priority], &(ptypeTaskHandle->list));

    /* 开启当前优先级 */
    g_cTaskPriorityValid[ptypeTaskHandle->priority] = 1;

    return 0;
}

int8_t cMicroTaskSuspend(MicroTaskType *ptypeTaskHandle)
{
    if(ptypeTaskHandle == NULL)
        return 1;

    if(ptypeTaskHandle->priority > MICRO_TASK_PRIORITY_MAX_VALUE)
        return 2;

    /* 从当前优先级任务链表中移除 */
    cMicroListRemove(&(ptypeTaskHandle->list));

    /* 当前优先级链表已经没有任务，关闭当前优先级 */
    if(g_typeMicroListTaskHead[ptypeTaskHandle->priority].pNext == &g_typeMicroListTaskHead[ptypeTaskHandle->priority])
        g_cTaskPriorityValid[ptypeTaskHandle->priority] = 0;

    return 0;
}

void vMicroTaskDelay(int64_t lTime)
{
    cMicroTaskSuspend(g_ptypeTaskCurrentHandle);

    cMicroDelay(g_ptypeTaskCurrentHandle, lTime);
}

void vMicroTaskDelayUntil(int64_t lTime)
{
    cMicroTaskSuspend(g_ptypeTaskCurrentHandle);

    cMicroDelayUntil(g_ptypeTaskCurrentHandle, lTime);
}

MicroTaskType *ptypeMicroTaskGreat(char *name, int8_t priority, void (*vFunction)(void *pvValue))
{
    MicroTaskType *ptypeTaskHandle = NULL;

    if(priority > MICRO_TASK_PRIORITY_MAX_VALUE)
        return NULL;

    if(vFunction == NULL)
        return NULL;

    ptypeTaskHandle = pvMicroMemCalloc(&g_typeMicroRTOSMemHead, 1, sizeof(MicroTaskType));
    if(ptypeTaskHandle == NULL)
        return NULL;

    memcpy(ptypeTaskHandle->name, name, (strlen(name) < MICRO_TASK_NAME_MAX_LENGTH) ? strlen(name) : MICRO_TASK_NAME_MAX_LENGTH - 1);
    ptypeTaskHandle->priority = priority;
    ptypeTaskHandle->vFunction = vFunction;
    ptypeTaskHandle->pElement = ptypeTaskHandle;

    ptypeTaskHandle->list.pElement = ptypeTaskHandle;

    /* 插入到当前优先级链表的最后  */
    cMicroListInsertEnd(&g_typeMicroListTaskHead[priority], &(ptypeTaskHandle->list));

    /* 开启当前优先级 */
    g_cTaskPriorityValid[ptypeTaskHandle->priority] = 1;

    return ptypeTaskHandle;
}

void vMicroTaskMachine(void)
{
    MicroListType *ptypeListNow = NULL, *ptypeListPrevious = NULL;
    MicroTaskType *ptypeTaskNow = NULL;
    int8_t cTaskPriorityFind = 0;

    /* 查找已经就绪的最高优先级任务 */
    for(cTaskPriorityFind = 0; cTaskPriorityFind < MICRO_TASK_PRIORITY_MAX_VALUE; ++cTaskPriorityFind)
    {
        if(g_cTaskPriorityValid[cTaskPriorityFind] != 0)
        {
            break;
        }
    }

    /* 轮询执行当前优先级下的全部就绪任务 */
    for(ptypeListPrevious = &g_typeMicroListTaskHead[cTaskPriorityFind]; \
        ptypeListPrevious->pNext != &g_typeMicroListTaskHead[cTaskPriorityFind]; \
        ptypeListPrevious = ptypeListPrevious->pNext)
    {
        ptypeListNow = ptypeListPrevious->pNext;

        ptypeTaskNow = ptypeListNow->pElement;

        /* 切换当前执行的任务 */
        g_ptypeTaskCurrentHandle = ptypeTaskNow;

        /* 执行任务函数 */
        ptypeTaskNow->vFunction(ptypeTaskNow);
    }
}
